#include <iostream>
using namespace std;

// Product

class Product {
public:
    Product() {
        cout << "Product..." << endl;
    }
};

// Builder

class Builder {
public:
    virtual void BuildPartA() = 0;
    virtual void BuildPartB() = 0;
    virtual void BuildPartC() = 0;
    virtual Product* GetProduct() = 0;
	 virtual void DestoryProduct(Product *p) = 0;
    virtual ~Builder() { }
	 Builder(){
		 product = new Product();
		 partADone = false;
		 partBDone = false;
		 partCDone = false;
	 }
protected:
	 Product *product;
	 bool partADone;
	 bool partBDone;
	 bool partCDone;
};

class ConcreteBuilder :public Builder {
public:
    void BuildPartA() {
	 	  if (! partADone){
			  cout << "BuildPartA..." << endl;
			  partADone = true;
		  }
    }

    void BuildPartB() {
		  if (! partBDone){
			  cout << "BuildPartB..." << endl;
			  partBDone = true;
		  }
    }

    void BuildPartC() {
		  if (! partCDone){
			  cout << "BuildPartC..." << endl;
			  partCDone = true;
		  }
    }

    Product* GetProduct() {
		  if (partADone && partBDone && partCDone){
		  		Product *tmp = product;
				product = new Product();
				partADone = false;
				partBDone = false;
				partCDone = false;
		  		return tmp;
		  }
        return NULL;
    }	 
	 void DestoryProduct(Product *p)
	 {
		 delete p; 
	 }
};

// Director

class Director {
public:
    Director(Builder* pBuilder) {
        _builer = pBuilder;
    }

    void Construct() {
        _builer->BuildPartA();
        _builer->BuildPartB();
        _builer->BuildPartC();
    }

private:
    Builder *_builer;
};


int main() {
    auto builder = new ConcreteBuilder();
    auto director = new Director(builder);
    director->Construct();
    Product* product = builder->GetProduct();

    delete product;
    delete builder;
    delete director;

    return 0;
}
